<template>
  <div>
    <div>
      <h4><b>审批人设置</b></h4>
      <el-radio-group v-model="dataType" @change="changeDataType">
        <el-radio label="USERS">指定用户</el-radio>
        <el-radio label="ROLES">角色</el-radio>
        <el-radio label="DEPTS">部门</el-radio>
        <el-radio label="INITIATOR">发起人</el-radio>
        <el-radio label="POST">岗位</el-radio>
      </el-radio-group>
    </div>
    <el-row>
      <div v-if="dataType === 'USERS'" class="mt-10px">
        <el-tag
          v-for="userText in selectedUser.text"
          :key="userText"
          effect="plain"
        >
          {{ userText }}
        </el-tag>
        <div class="element-drawer__button">
          <el-button type="primary" icon="el-icon-plus" @click="onSelectusers()"
            >添加用户</el-button
          >
        </div>
      </div>
      <div v-if="dataType === 'ROLES'" class="w-90%">
        <el-select
          v-model="roleIds"
          multiple
          placeholder="请选择角色"
          @change="changeSelectroles"
          class="mt-10px w-100%"
        >
          <el-option
            v-for="item in roleOptions"
            :key="item.roleId"
            :label="item.roleName"
            :value="`ROLE${item.roleId}`"
            :disabled="item.status === 1"
          >
          </el-option>
        </el-select>
      </div>
      <div v-if="dataType === 'DEPTS'" class="w-90%">
        <!-- <tree-select
                    :width="320"
                    :height="400"
                    :data="deptTreeData"
                    :defaultProps="deptProps"
                    multiple
                    clearable
                    checkStrictly
                    nodeKey="id"
                    :checkedKeys="deptIds"
                    @change="checkedDeptChange"
                >
                </tree-select> -->
        <el-tree-select
          ref="companyIdRef"
          clearable
          class="mt-10px w-100%"
          v-model="deptIds"
          :data="deptTreeData"
          multiple
          @change="checkedDeptChange"
          :props="{
            value: 'id',
            label: 'label',
            children: 'children'
          }"
          placeholder="请选择归属单位"
          value-key="id"
          filterable
        />
      </div>
      <div v-if="dataType === 'POST'" class="w-90%">
        <el-select
          v-model="postIds"
          placeholder="请选择岗位"
          @change="changeSelectPost"
          class="mt-10px w-100%"
        >
          <el-option
            v-for="item in postOptions"
            :key="item.postCode"
            :label="item.postName"
            :value="`POST${item.postCode}`"
          >
          </el-option>
        </el-select>
      </div>
    </el-row>
    <el-row>
      <div v-show="showMultiFlog">
        <el-divider />
        <h4><b>多实例审批方式</b></h4>
        <el-row :span="24">
          <el-radio-group
            v-model="multiLoopType"
            @change="changeMultiLoopType()"
          >
            <el-row><el-radio label="Null">无</el-radio></el-row>
            <el-row
              ><el-radio label="SequentialMultiInstance" class="ml-10px"
                >会签（需所有审批人同意）</el-radio
              ></el-row
            >
            <el-row
              ><el-radio label="ParallelMultiInstance"
                >或签（一名审批人同意即可）</el-radio
              ></el-row
            >
          </el-radio-group>
        </el-row>
        <el-row v-if="multiLoopType !== 'Null'">
          <el-tooltip
            content="开启后，实例需按顺序轮流审批"
            placement="top-start"
            @click.stop.prevent
          >
            <el-icon><InfoFilled /></el-icon>
          </el-tooltip>
          <span class="custom-label">顺序审批：</span>
          <el-switch v-model="isSequential" @change="changeMultiLoopType()" />
        </el-row>
      </div>
    </el-row>
    <!-- 弹出框下拉框 -->
    <SelectDialog
      :dialog-param="dialogParamUse"
      @ok="selectDialogData"
      @close="closeFn"
    ></SelectDialog>
  </div>
</template>

<script setup lang="ts" name="UserTask">
import { getPricipalId } from '@/utils/commo'
import { listRole } from '@/api/system/role'
import { getPostList } from '@/api/workflow/model'
import { companyOptions } from '@/hooks/dict/useProject'
import useCommonStore from '@/store/modules/common'
import { getListByCustomerName } from '@/api/customerManage/customerList'
const commonStore = useCommonStore()
const { proxy } = getCurrentInstance()
const props = defineProps({
  id: String,
  type: String
})
const userTaskForm = ref({
  dataType: '',
  assignee: '',
  candidateUsers: '',
  candidateGroups: '',
  text: ''
})
const data = reactive({
  loading: false,
  dataType: 'USERS',
  selectedUser: {
    // 指定用户 选中的人
    ids: [], //传递给后端
    text: [], //文字展示
    uuids: [] //前端使用
  },
  userOpen: false,
  deptName: undefined,
  deptOptions: [],
  deptProps: {
    children: 'children',
    label: 'label'
  },
  deptTempOptions: [],
  userTableList: [],
  userTotal: 0,
  selectedUserDate: [],
  roleOptions: [],
  roleIds: [],
  deptTreeData: [],
  deptIds: [],
  postIds: null, //岗位
  postOptions: [], //岗位下拉框选择数据
  // 查询参数
  queryParams: {
    deptId: undefined
  },
  showMultiFlog: false,
  isSequential: false,
  multiLoopType: 'Null'
})
const {
  dataType,
  selectedUser,
  deptOptions,
  deptProps,
  postIds,
  postOptions,
  selectedUserDate,
  roleOptions,
  roleIds,
  deptTreeData,
  deptIds,
  // 查询参数
  showMultiFlog,
  isSequential,
  multiLoopType
} = toRefs(data)
const bpmnElement = ref(null)
const multipleTable = ref()
const multiLoopInstance = ref(null)
const bpmnInstances = () => (window as any)?.bpmnInstances
function resetTaskForm() {
  const bpmnElementObj = bpmnElement.value?.businessObject
  if (!bpmnElementObj) {
    return
  }
  clearOptionsData()
  dataType.value = bpmnElementObj['dataType']
  if (dataType.value === 'USERS') {
    let userIdData =
      bpmnElementObj['candidateUsers'] || bpmnElementObj['assignee']
    let userText = bpmnElementObj['text'] || []
    if (
      userIdData &&
      userIdData.toString().length > 0 &&
      userText &&
      userText.length > 0
    ) {
      selectedUser.value.ids = userIdData?.toString().split(',')
      selectedUser.value.text = userText?.split(',')
    }
    if (selectedUser.value.ids.length > 1) {
      showMultiFlog.value = true
    }
  } else if (dataType.value === 'ROLES') {
    getRoleOptions()
    let roleIdData = bpmnElementObj['candidateGroups'] || []
    if (roleIdData && roleIdData.length > 0) {
      roleIds.value = roleIdData.split(',')
    }
    showMultiFlog.value = true
  } else if (dataType.value === 'DEPTS') {
    getDeptData('set', bpmnElementObj['candidateGroups'])
    showMultiFlog.value = true
  } else if (dataType.value == 'POST') {
    //岗位
    getPostData('set', bpmnElementObj['candidateGroups'])
    showMultiFlog.value = true
  }
  getElementLoop(bpmnElementObj)
}
/**
 * 清空选项数据
 */
function clearOptionsData() {
  selectedUser.value.ids = []
  selectedUser.value.text = []
  roleIds.value = []
  postIds.value = null
  deptIds.value = []
}
/**
 * 跟新节点数据
 */
function updateElementTask() {
  const taskAttr = Object.create(null)
  for (let key in userTaskForm.value) {
    taskAttr[key] = userTaskForm.value[key]
  }
  bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), taskAttr)
}
// /**
//  * 查询部门下拉树结构（含部门前缀）
//  */
// function getDeptTreeData() {
//     function refactorTree(data) {
//         return data.map(node => {
//             let treeData = {
//                 id: `DEPT${node.id}`,
//                 label: node.label,
//                 parentId: node.parentId,
//                 weight: node.weight,
//             }
//             if (node.children && node.children.length > 0) {
//                 treeData.children = refactorTree(node.children)
//             }
//             return treeData
//         })
//     }
//     return new Promise((resolve, reject) => {
//         if (!deptTreeData.value || deptTreeData.value.length <= 0) {
//             getDeptOptions()
//                 .then(() => {
//                     deptTreeData.value = refactorTree(deptOptions.value)
//                     resolve()
//                 })
//                 .catch(() => {
//                     reject()
//                 })
//         } else {
//             resolve()
//         }
//     })
// }
/**部门 数据 start*/

async function getDeptData(type, Data) {
  let comRes = await commonStore.getDepartmentData()
  deptTreeData.value = comRes
  if (type == 'set') {
    let deptIdData = Data || []
    if (deptIdData && deptIdData.length > 0) {
      deptIdData = deptIdData.split(',')
      deptIds.value = deptIdData.map(item => {
        return parseInt(item)
      })
    }
  }
}
/***部门 end*/
/***获取岗位数据 */
async function getPostData(type, Data) {
  let comRes = await getPostList()
  postOptions.value = comRes
  if (type == 'set') {
    postIds.value = Data
  }
}
/***岗位选择事件 */
function changeSelectPost(val) {
  let groups = null
  let text = null
  if (val) {
    userTaskForm.value.dataType = 'POST'
    groups = val || null
    let textArr = postOptions.value.filter(
      k => val.indexOf(`POST${k.postCode}`) >= 0
    )
    text = textArr?.map(k => k.postName).join() || null
  } else {
    userTaskForm.value.dataType = null
    multiLoopType.value = 'Null'
  }
  userTaskForm.value.candidateGroups = groups
  userTaskForm.value.text = text
  updateElementTask()
  changeMultiLoopType()
}
/**
 * 获取角色列表
 */
function getRoleOptions() {
  if (!roleOptions.value || roleOptions.value.length <= 0) {
    listRole().then(response => (roleOptions.value = response.rows))
  }
}

/****** 指定用户 start*/
const dialogParamUse = ref({}) //选择人员弹出框
// 添加用户
function onSelectusers() {
  selectedUserDate.value = []
  multipleTable.value?.clearSelection()
  dialogParamUse.value = {
    type: 'principalId',
    title: '指定用户',
    dataType: 'person',
    nodeKey: 'uuid',
    multiple: true,
    checkStrictly: false
  }
  dialogParamUse.value.isDialog = true
  dialogParamUse.value.defaultCheckedKeys = selectedUser.value.ids || []
}

/** 弹出框下拉框
 * @param {*} val  selectDialog组件返回的值
 */
const selectDialogData = val => {
  switch (val.type) {
    case 'principalId':
      userTaskForm.dataType = 'USERS'
      selectedUser.value.text = val.labelData //选中的文本
      selectedUser.value.ids = getPricipalId(
        val.selectData,
        val.defaultCheckedKeys
      )
      selectedUser.value.uuids = val.defaultCheckedKeys
        ? val.defaultCheckedKeys
        : null
      let newarr = val.labelData.toString()
      if (val.labelData && newarr.indexOf(',') == -1) {
        userTaskForm.value.assignee = getPricipalId(
          val.selectData,
          val.defaultCheckedKeys
        ).toString()
        userTaskForm.value.text = val.labelData.toString()
        userTaskForm.value.candidateUsers = null
        showMultiFlog.value = false
        multiLoopType.value = 'Null'
        changeMultiLoopType()
      } else {
        userTaskForm.value.candidateUsers = getPricipalId(
          val.selectData,
          val.defaultCheckedKeys
        )
        userTaskForm.value.text = val.labelData
        userTaskForm.value.assignee = null
        showMultiFlog.value = true
      }
      updateElementTask()
      break
  }
}
const closeFn = val => {
  dialogParamUse.value.isDialog = false
}
/****** 指定用户 end*/
function changeSelectroles(val) {
  let groups = null
  let text = null
  if (val && val.length > 0) {
    userTaskForm.value.dataType = 'ROLES'
    groups = val.join() || null
    let textArr = roleOptions.value.filter(
      k => val.indexOf(`ROLE${k.roleId}`) >= 0
    )
    text = textArr?.map(k => k.roleName).join() || null
  } else {
    userTaskForm.value.dataType = null
    multiLoopType.value = 'Null'
  }
  userTaskForm.value.candidateGroups = groups
  userTaskForm.value.text = text
  updateElementTask()
  changeMultiLoopType()
}
function checkedDeptChange(checkedIds) {
  let groups = null
  let text = null
  deptIds.value = checkedIds
  if (checkedIds && checkedIds.length > 0) {
    userTaskForm.value.dataType = 'DEPTS'
    groups = checkedIds.join() || null
    let textArr = []
    let treeStarkData = JSON.parse(JSON.stringify(deptTreeData.value))
    checkedIds.forEach(id => {
      let stark = []
      stark = stark.concat(treeStarkData)
      while (stark.length) {
        let temp = stark.shift()
        if (temp.children) {
          stark = temp.children.concat(stark)
        }
        if (id === temp.id) {
          textArr.push(temp)
        }
      }
    })
    text = textArr?.map(k => k.label).join() || null
  } else {
    userTaskForm.value.dataType = null
    multiLoopType.value = 'Null'
  }
  userTaskForm.value.candidateGroups = groups
  userTaskForm.value.text = text
  updateElementTask()
  changeMultiLoopType()
}
// 审批人设置选择事件
function changeDataType(val) {
  if (
    val === 'ROLES' ||
    val === 'DEPTS' ||
    val === 'POST' ||
    (val === 'USERS' && selectedUser.value.ids.length > 1)
  ) {
    showMultiFlog.value = true
  } else {
    showMultiFlog.value = false
  }
  multiLoopType.value = 'Null'
  changeMultiLoopType()
  // 清空 userTaskForm 所有属性值
  Object.keys(userTaskForm.value).forEach(
    key => (userTaskForm.value[key] = null)
  )
  userTaskForm.value.dataType = val
  if (val === 'USERS') {
    if (
      selectedUser.value &&
      selectedUser.value.ids &&
      selectedUser.value.ids.length > 0
    ) {
      if (selectedUser.value.ids.length === 1) {
        userTaskForm.value.assignee = selectedUser.value.ids[0]
      } else {
        userTaskForm.value.candidateUsers = selectedUser.value.ids.join()
      }
      userTaskForm.value.text = selectedUser.value.text?.join() || null
    }
  } else if (val === 'ROLES') {
    getRoleOptions()
    if (roleIds.value && roleIds.value.length > 0) {
      userTaskForm.value.candidateGroups = roleIds.value.join() || null
      let textArr = roleOptions.value.filter(
        k => roleIds.value.indexOf(`ROLE${k.roleId}`) >= 0
      )
      userTaskForm.value.text = textArr?.map(k => k.roleName).join() || null
    }
  } else if (val === 'DEPTS') {
    // getDeptTreeData()
    getDeptData()
    if (deptIds.value && deptIds.value.length > 0) {
      userTaskForm.value.candidateGroups = deptIds.value.join() || null
      let textArr = []
      let treeStarkData = JSON.parse(JSON.stringify(deptTreeData.value))
      deptIds.value.forEach(id => {
        let stark = []
        stark = stark.concat(treeStarkData)
        while (stark.length) {
          let temp = stark.shift()
          if (temp.children) {
            stark = temp.children.concat(stark)
          }
          if (id === temp.id) {
            textArr.push(temp)
          }
        }
      })
      userTaskForm.value.text = textArr?.map(k => k.label).join() || null
    }
  } else if (val === 'POST') {
    getPostData()
    if (postIds.value) {
      userTaskForm.value.candidateGroups = postIds.value || null
      let textArr = postOptions.value.filter(
        k => postIds.value.indexOf(`POST${k.postCode}`) >= 0
      )
      userTaskForm.value.text = textArr?.map(k => k.postName).join() || null
    }
  } else if (val === 'INITIATOR') {
    userTaskForm.value.assignee = '${initiator}'
    userTaskForm.value.text = '流程发起人'
  }
  updateElementTask()
}
function getElementLoop(businessObject) {
  if (!businessObject.loopCharacteristics) {
    multiLoopType.value = 'Null'
    return
  }
  isSequential.value = businessObject.loopCharacteristics.isSequential
  if (businessObject.loopCharacteristics.completionCondition) {
    if (
      businessObject.loopCharacteristics.completionCondition.body ===
      '${nrOfCompletedInstances >= nrOfInstances}'
    ) {
      multiLoopType.value = 'SequentialMultiInstance'
    } else {
      multiLoopType.value = 'ParallelMultiInstance'
    }
  }
}
function changeMultiLoopType() {
  console.log(multiLoopType.value, 'multiLoopType.value--')
  // 取消多实例配置
  if (multiLoopType.value == 'Null') {
    bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
      loopCharacteristics: null,
      assignee: null
    })
    return
  }
  multiLoopInstance.value = bpmnInstances().moddle.create(
    'bpmn:MultiInstanceLoopCharacteristics',
    {
      isSequential: isSequential.value
    }
  )
  // 更新多实例配置
  bpmnInstances().modeling.updateProperties(toRaw(bpmnElement.value), {
    loopCharacteristics: multiLoopInstance.value,
    assignee: '${assignee}'
  })
  // 完成条件
  let completionCondition = null
  // 会签
  if (multiLoopType.value === 'SequentialMultiInstance') {
    completionCondition = bpmnInstances().moddle.create(
      'bpmn:FormalExpression',
      {
        body: '${nrOfCompletedInstances >= nrOfInstances}'
      }
    )
  }
  // 或签
  if (multiLoopType.value === 'ParallelMultiInstance') {
    completionCondition = bpmnInstances().moddle.create(
      'bpmn:FormalExpression',
      {
        body: '${nrOfCompletedInstances > 0}'
      }
    )
  }
  // 更新模块属性信息
  bpmnInstances().modeling.updateModdleProperties(
    toRaw(bpmnElement.value),
    multiLoopInstance.value,
    {
      collection: '${multiInstanceHandler.getUserIds(execution)}',
      elementVariable: 'assignee',
      completionCondition
    }
  )
}
watch(
  () => props.id,
  () => {
    bpmnElement.value = bpmnInstances().bpmnElement
    nextTick(() => {
      resetTaskForm()
    })
  },
  { immediate: true }
)
onBeforeUnmount(() => {
  bpmnElement.value = null
})
</script>

<style scoped lang="scss">
.el-row .el-radio-group {
  margin-bottom: 15px;
  .el-radio {
    line-height: 28px;
  }
}
.el-tag {
  margin-bottom: 10px;
  + .el-tag {
    margin-left: 10px;
  }
}

.custom-label {
  padding-left: 5px;
  font-weight: 500;
  font-size: 14px;
  color: #606266;
}
</style>
